package com.dudu.utils;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import com.dudu.service.ILogService;
import com.dudu.service.impl.LogService;

import core.CoreService;
import core.util.IoUtils;

public class HttpRequest {

	private static ILogService logService = new LogService();

	/**
	 * 未使用
	 * 
	 * @param path
	 * @return
	 */
	public static String commintString(String path) {

		String ret = null;
		HttpURLConnection conn = null;
		InputStream inStream = null;
		try {
			URL url = new URL(path);
			conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(25 * 1000);
			conn.setRequestMethod("POST");
			// conn.setRequestProperty("Accept-Charset", "utf-8");
			// conn.setRequestProperty("contentType", "utf-8");
			conn.setRequestProperty("Accept-Charset", "UTF-8");
			// conn.setRequestProperty("contentType", "gbk");
			conn.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded;charset=UTF-8");//

			inStream = conn.getInputStream();
			byte[] data = HttpRequest.readStream(inStream);
			if (data != null) {
				ret = new String(data, "utf-8");
			}

		} catch (SocketTimeoutException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			IoUtils.close(conn);
			IoUtils.close(inStream);
		}

		return ret;

	}

	/**
	 * GET方式 普通使用
	 * 
	 * @param path
	 * @return
	 */
	public static String getData(String path) {

		String ret = null;
		HttpURLConnection conn = null;
		InputStream inStream = null;
		try {

			URL url = new URL(path);
			conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(25 * 1000);
			conn.setReadTimeout(25 * 1000);
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Accept-Charset", "utf-8");
			conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");

			conn.setDoOutput(true);
			conn.setDoInput(true);

			if (conn.getResponseCode() == 200) {

				inStream = conn.getInputStream();
				byte[] data1 = HttpRequest.readStream(inStream);

				if (data1 != null) {
					ret = new String(data1, "utf-8");
				}
			}

		} catch (SocketTimeoutException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			IoUtils.close(inStream);
			IoUtils.close(conn);
		}

		return ret;
	}

	/**
	 * 专门用于语音短信发送使用
	 * 
	 * @param path
	 * @return
	 */
	public static String getPostToVoice(String path) {

		String ret = null;
		HttpURLConnection conn = null;
		InputStream inStream = null;
		try {

			URL url = new URL(path);
			conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(25 * 1000);
			conn.setReadTimeout(25 * 1000);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded;charset=UTF-8");

			conn.setDoOutput(true);
			conn.setDoInput(true);

			if (conn.getResponseCode() == 200) {

				inStream = conn.getInputStream();
				byte[] data1 = HttpRequest.readStream(inStream);

				if (data1 != null) {
					ret = new String(data1, "utf-8");
				}
			}

		} catch (SocketTimeoutException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			IoUtils.close(inStream);
			IoUtils.close(conn);
		}

		return ret;
	}

	/**
	 * POST XML
	 * 
	 * @param url
	 * @param param
	 * @return
	 */
	public static String postXml(String url, String param) {
		double begin = Calendar.getInstance().getTimeInMillis();
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			URLConnection conn = realUrl.openConnection(); // 打开和URL之间的连接
			conn.setRequestProperty("accept", "application/xml"); // 设置通用的请求属性
			conn.setRequestProperty("connection", "close");
			conn.setRequestProperty("content-type",
					"application/xml;charset=UTF-8");
			conn.setDoOutput(true); // 发送POST请求必须设置如下两行
			conn.setDoInput(true);
			out = new PrintWriter(conn.getOutputStream());// 获取URLConnection对象对应的输出流
			out.print(param);// 发送请求参数
			out.flush();// flush输出流的缓冲
			in = new BufferedReader(new InputStreamReader(
					conn.getInputStream(), Charset.forName("UTF-8")));// 定义BufferedReader输入流来读取URL的响应
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {// 使用finally块来关闭输出流、输入流
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		// 接口调用结束时间
		double end = Calendar.getInstance().getTimeInMillis();
		// 时间差
		double during = Double.valueOf((end - begin)) / 1000;

		CoreService.log.info("时长(单位:秒)：" + during + "；url:" + url + ";req:"
				+ param + ";response=" + result);

		return result;
	}

	/**
	 * POST 方式传JSON
	 * 
	 * @param path
	 * @param data
	 * @return
	 */
	public static String postData(String path, String data) {
		double begin = Calendar.getInstance().getTimeInMillis();
		String ret = "";
		HttpURLConnection conn = null;
		OutputStream output = null;
		InputStream inStream = null;
		try {
			URL url = new URL(path);
			conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(60 * 1000);
			conn.setReadTimeout(60 * 1000);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Accept-Charset", "utf-8");
			conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
			conn.setRequestProperty("Content-Length", String.valueOf(data.getBytes().length));
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.connect();
			output = conn.getOutputStream();
			output.write(data.getBytes());// 输入参数
			output.flush();
			if (conn.getResponseCode() == 200) {
				inStream = conn.getInputStream();
				byte[] data1 = HttpRequest.readStream(inStream);
				if (data1 != null) {
					ret = new String(data1, "utf-8");
				}
			} else {
				inStream = conn.getErrorStream();
				byte[] data1 = HttpRequest.readStream(inStream);

				if (data1 != null) {
					ret = new String(data1, "utf-8");
				}
			}

		} catch (SocketTimeoutException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			IoUtils.close(inStream);
			IoUtils.close(output);
			IoUtils.close(conn);
		}
		// 接口调用结束时间
		double end = Calendar.getInstance().getTimeInMillis();
		// 时间差
		double during = Double.valueOf((end - begin)) / 1000;
		CoreService.log.info("时长(单位:秒)：" + during + "；url:" + path + ";req="
				+ data + ";response=" + ret);
		logService.saveOperationPlatformLog(during, path, data, ret);
		return ret;

	}

	public static InputStream getInputStream(String path) throws IOException {
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(5 * 1000);
		conn.setRequestMethod("POST");
		InputStream inStream = conn.getInputStream();
		return inStream;

	}

	public static byte[] readStream(InputStream inStream) throws IOException,
			SocketTimeoutException {
		byte[] buffer = new byte[1024];
		int len = -1;
		byte[] data;
		ByteArrayOutputStream outStream = null;
		try {
			outStream = new ByteArrayOutputStream();
			while ((len = inStream.read(buffer)) != -1) {
				outStream.write(buffer, 0, len);
			}
			data = outStream.toByteArray();
		} finally {
			IoUtils.close(outStream);
			IoUtils.close(inStream);
		}
		return data;
	}

	/**
	 * GET方式调用三次
	 * 
	 * @param path
	 * @return
	 */
	public static String getDataThreeTime(String path) {

		int times = 0;

		String ret = null;
		try {
			ret = getData(path);
		} catch (Exception e) {
			e.printStackTrace();
			times++;
			if (times < 3) {
				try {
					ret = getData(path);
				} catch (Exception e1) {
					e1.printStackTrace();
					times++;
					if (times < 3) {
						try {
							ret = getData(path);
						} catch (Exception e2) {
							e2.printStackTrace();
						}
					}
				}
			}
		}

		return ret;
	}

	/**
	 * 容联专用 向指定 URL 发送POST方法的请求
	 * 
	 * @param AccountSid
	 * @param timestamp
	 * @param url
	 *            发送请求的 URL
	 * @param param
	 *            请求参数
	 * @return 所代表远程资源的响应结果
	 */
	public static String sendRongLianPost(String AccountSid, String timestamp,
			String url, String param) {
		double begin = Calendar.getInstance().getTimeInMillis();
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			String src = AccountSid + ":" + timestamp;// 生成auth
			String auth = new sun.misc.BASE64Encoder().encode(src.getBytes());
			URL realUrl = new URL(url);
			URLConnection conn = realUrl.openConnection(); // 打开和URL之间的连接
			conn.setRequestProperty("accept", "application/xml"); // 设置通用的请求属性
			conn.setRequestProperty("connection", "close");
			conn.setRequestProperty("content-type",
					"application/xml;charset=UTF-8");
			conn.setRequestProperty("authorization", auth);
			conn.setDoOutput(true); // 发送POST请求必须设置如下两行
			conn.setDoInput(true);
			out = new PrintWriter(conn.getOutputStream());// 获取URLConnection对象对应的输出流
			out.print(param);// 发送请求参数
			out.flush();// flush输出流的缓冲
			in = new BufferedReader(new InputStreamReader(
					conn.getInputStream(), Charset.forName("UTF-8")));// 定义BufferedReader输入流来读取URL的响应
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {// 使用finally块来关闭输出流、输入流
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		// 接口调用结束时间
		double end = Calendar.getInstance().getTimeInMillis();
		// 时间差
		double during = Double.valueOf((end - begin)) / 1000;

		CoreService.log.info("时长(单位:秒)：" + during + "；url:" + url + ";req:"
				+ param + ";response=" + result);

		return result;
	}

	/**
	 * 容联专用 上传文件
	 * 
	 * @param AccountSid
	 * @param timestamp
	 * @param url
	 * @param filePath
	 * @return
	 */
	public static String postRongLianFile(String AccountSid, String timestamp,
			String url, String filePath) {
		String result = "";
		double begin = Calendar.getInstance().getTimeInMillis();
		FileInputStream fis = null;
		DefaultHttpClient httpclient = new DefaultHttpClient();
		try {
			String src = AccountSid + ":" + timestamp;// 生成auth
			String auth = new sun.misc.BASE64Encoder().encode(src.getBytes());
			HttpPost httppost = new HttpPost(url);
			// 指定请求头信息
			httppost.setHeader("Accept", "application/xml");
			httppost.setHeader("connection", "close");
			httppost.setHeader("Content-Type",
					"application/octet-stream;charset=utf-8");
			httppost.setHeader("authorization", auth);

			// 默认字符编码
			BasicHttpEntity requestBody = new BasicHttpEntity();

			fis = new FileInputStream(filePath);
			// 打印请求方法、URL以及HTTP协议版本
			CoreService.log.info("Executing request: "
					+ httppost.getRequestLine());

			requestBody.setContent(fis);
			requestBody.setContentLength(fis.available());
			httppost.setEntity(requestBody);

			// 执行客户端请求
			HttpResponse response = httpclient.execute(httppost);
			HttpEntity entity = response.getEntity();// 获取响应实体信息

			// 默认字符编码
			String defaultCharset = "UTF-8";
			if (entity != null) {
				// 打印服务端响应内容
				result = EntityUtils.toString(entity, defaultCharset);
			}
			EntityUtils.consume(entity);// 确保HTTP响应内容全部被读出或者内容流被关闭
			// 接口调用结束时间
			double end = Calendar.getInstance().getTimeInMillis();
			// 时间差
			double during = Double.valueOf((end - begin)) / 1000;
			CoreService.log.info("时长(单位:秒)：" + during + "；url:" + url + ";req:"
					+ ";response=" + result);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			// 关闭连接
			httpclient.getConnectionManager().shutdown();
		}
		return result;
	}

	/**
	 * 带文件上传的post, file,form
	 * 
	 * @param path
	 * @param params
	 * @param file
	 */
	public static String postFile(String path, HashMap<String, String> params,
			File file) throws IOException {
		// path为传送地址
		URL url = new URL(path);

		// 创建连接
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setDoOutput(true);// 允许对外发送请求参数
		conn.setUseCaches(false);// 不进行缓存
		conn.setConnectTimeout(5 * 1000);
		// 传送方式
		conn.setRequestMethod("POST");

		conn.setRequestProperty(
				"Accept",
				"image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
		conn.setRequestProperty("Accept-Language", "zh-CN");
		conn.setRequestProperty(
				"User-Agent",
				"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
		conn.setRequestProperty("Content-Type",
				"multipart/form-data; boundary=--testsssssss");
		// conn.setRequestProperty("Content-Type",
		// "application/x-www-form-urlencoded,*/*");
		conn.setRequestProperty("Connection", "Keep-Alive");
		if (params != null && !params.isEmpty()) {

			for (Map.Entry<String, String> entry : params.entrySet()) {
				conn.setRequestProperty(entry.getKey(), entry.getValue());
			}
		}
		// 输出
		OutputStream outStream = conn.getOutputStream();
		if (file != null) {
			// data为文件流信息
			InputStream is = new FileInputStream(file);

			byte[] bytes = new byte[1024];
			int len = 0;

			while ((len = is.read(bytes)) != -1) {
				outStream.write(bytes, 0, len);
			}
			is.close();
		}
		outStream.flush();
		outStream.close();
		if (conn.getResponseCode() == 200) {
			InputStream input = conn.getInputStream();
			StringBuffer sb1 = new StringBuffer();
			int ss;
			while ((ss = input.read()) != -1) {
				sb1.append((char) ss);

			}
			return sb1.toString();
		} else {
			return conn.getResponseCode() + "";
		}
	}

	/**
	 * POST 请求 Form表单
	 * 
	 * @param RequestURL
	 * @param params
	 * @return
	 */
	public static String post(String RequestURL, StringBuffer params) {
		String result = null;
		try {
			URL url = new URL(RequestURL);

			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(30 * 1000);
			conn.setConnectTimeout(30 * 1000);
			conn.setDoInput(true); // 允许输入流
			conn.setDoOutput(true); // 允许输出流
			conn.setUseCaches(false); // 不允许使用缓存
			conn.setRequestMethod("POST"); // 请求方式
			conn.setDoOutput(true);// 是否输入参数
			conn.setRequestProperty("Charset", "utf-8"); // 设置编码
			conn.setRequestProperty("connection", "keep-alive");
			conn.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			byte[] bypes = params.toString().getBytes();
			// System.out.println(params.toString());
			DataOutputStream out = new DataOutputStream(conn.getOutputStream());
			out.write(bypes);// 输入参数
			/**
			 * 获取响应码 200=成功 当响应成功，获取响应的流
			 */
			int res = conn.getResponseCode();
			// System.out.println("----response code:" + res);
			// {

			// System.out.println("request success");

			InputStream input = conn.getInputStream();
			StringBuffer sb1 = new StringBuffer();

			int ss;
			while ((ss = input.read()) != -1) {
				sb1.append((char) ss);

			}
			result = sb1.toString();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();

		}
		return result;

	}

	/**
	 * 天亿文件上传
	 * 
	 * @param path
	 * @param param
	 * @param myfile
	 * @return
	 * @throws Exception
	 */
	public static String sendHttpPostRequest(String path, JSONObject param,
			String myfile) throws Exception {
		double begin = Calendar.getInstance().getTimeInMillis();
		String ret = null;
		HttpURLConnection conn = null;
		OutputStream output = null;
		InputStream inStream = null;
		try {
			String content = "";
			File file = new File(myfile);
			InputStream is = new FileInputStream(file);
			byte[] bytes = new byte[1024];
			int len = 0;
			while ((len = is.read(bytes)) != -1) {
				content = content + EnumUtility.bytesToHexString(bytes);
			}
			is.close();
			param.put("contents", content);
			URL url = new URL(path);
			conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(25 * 1000);
			conn.setReadTimeout(25 * 1000);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Accept-Charset", "utf-8");
			conn.setRequestProperty("Content-Type",
					"application/json; charset=utf-8");
			conn.setRequestProperty("Content-Length",
					String.valueOf(param.toString().getBytes().length));

			conn.setDoOutput(true);
			conn.setDoInput(true);

			conn.connect();

			output = conn.getOutputStream();
			output.write(param.toString().getBytes());// 输入参数
			output.flush();
			if (conn.getResponseCode() == 200) {

				inStream = conn.getInputStream();
				byte[] data1 = HttpRequest.readStream(inStream);

				if (data1 != null) {
					ret = new String(data1, "utf-8");
				}
			} else {
				// System.out.println(conn.getResponseCode());
				inStream = conn.getErrorStream();
				byte[] data1 = HttpRequest.readStream(inStream);

				if (data1 != null) {
					ret = new String(data1, "utf-8");
				}
			}

		} catch (SocketTimeoutException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			IoUtils.close(inStream);
			IoUtils.close(output);
			IoUtils.close(conn);
		}
		// 接口调用结束时间
		double end = Calendar.getInstance().getTimeInMillis();
		// 时间差
		double during = Double.valueOf((end - begin)) / 1000;
		CoreService.log.info("时长(单位:秒)：" + during + "；url:" + path
				+ ";response=" + ret);
		return ret;

	}

	public static void main(String[] args) {
		/*
		 * String url = "http://localhost/rlcallback/DialBillBack.do"; String
		 * param = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+ "<CDR>"+
		 * "<orderid>CM1013020170315135408461864</orderid>"+ "<CallerCdr>"+
		 * "<appId>aaf98f8952624f610152764c995d228a</appId>"+
		 * "<callSid>1703151354088217000101300042e4da</callSid>"+
		 * "<subId>dfd9a01d766311e6997a6c92bf2c165d</subId>"+
		 * "<caller>01053827803</caller>"+ "<called>17001090122</called>"+
		 * "<starttime></starttime>"+ "<endtime></endtime>"+
		 * "<duration>0</duration>"+
		 * "<beginCallTime>20170315132013</beginCallTime>"+
		 * "<ringingBeginTime>20170315132017</ringingBeginTime>"+
		 * "<ringingEndTime>20170315132024</ringingEndTime>"+
		 * "<byetype>-10</byetype>"+ "<lostRate>0.01</lostRate>"+
		 * "<lineNumber>628</lineNumber>"+ "</CallerCdr>"+ "<CalledCdr>"+
		 * "<appId>aaf98f8952624f610152764c995d228a</appId>"+
		 * "<callSid>1703151354088217000101300042e4da</callSid>"+
		 * "<subId>dfd9a01d766311e6997a6c92bf2c165d</subId>"+
		 * "<caller>17001090122</caller>"+ "<called>18662187762</called>"+
		 * "<starttime></starttime>"+ "<endtime></endtime>"+
		 * "<duration>0</duration>"+
		 * "<beginCallTime>20170315132024</beginCallTime>"+
		 * "<ringingBeginTime>20170315132033</ringingBeginTime>"+
		 * "<ringingEndTime>20170315132050</ringingEndTime>"+
		 * "<lineNumber>628</lineNumber>"+ "</CalledCdr></CDR>";
		 */

		// String url = "http://localhost/chengqiCallback/StatusCallBack.do";
		String param = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><callstatusService version=\"1.0\"><service name=\"callstatusRequest\">"
				+ "<callid>C20170322150946AC102A3D0503048531</callid>"
				+ "<caller>18662187762</caller><callee>17001090122</callee><userflag>cancelcall</userflag>"
				+ "<callstatus>discontected</callstatus>"
				+ "<errorcode>0</errorcode><timestamp>20170322151012</timestamp><messageID>1016c085-272b-449f-ab1d-19d1ae5c0193</messageID></service></callstatusService>";

		// HttpRequest.postXml(url, param);

	}
}
